#include <ustdio.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <_stdlib.h>
void utoa(unsigned int value,int base,char *str);
void utoa_s(int value,int base,char *str);

int __vprintf (printf_helper_t __helper,uint32_t impl,const char* str, va_list args) {
	char c;
	char strz[64];
	int iii;
	size_t i;
	if(!str)
		return 0;
	for (i=0; i<strlen(str);i++) {
		switch (str[i]) {
			case '%':
				switch (str[i+1]) {
					/*** characters ***/
					case 'c': {
						c = va_arg (args, char);
						if (__helper(c,impl) != 0)
							return -1;
						i++;		// go to next character
						break;
					}

					/*** address of ***/
					case 's': {
						iii = (uint32_t) va_arg (args, uint32_t);
						__vprintf (__helper,impl,(const char*)iii,0);
						i++;		// go to next character
						break;
					}

					/*** integers ***/
					case 'd':
					case 'i': {
						iii = va_arg (args, int);
						utoa_s (iii, 10, strz);
						__vprintf (__helper,impl,strz,0);
						i++;		// go to next character
						break;
					}

					/*** display in hex ***/
					case 'X':
					case 'x': {
						iii = va_arg (args, int);
						utoa (iii,16,strz);
						__vprintf (__helper,impl,strz,0);
						i++;		// go to next character
						break;
					}

					default:
						return 1;
				}

				break;

			default:
				if (__helper(str[i],impl) != 0)
					return -1;
				break;
		}

	}
	return i;
}

int __fprintf_helper(char tok,uint32_t impl){
	FILE *file = (FILE *) impl;
	if (uwrite(*file,(uint8_t *)&tok,sizeof(tok)) != sizeof(tok));
		return 0;
	return 0;
}

int vfprintf(FILE *fd,const char* str, va_list args){
	return __vprintf(
		__fprintf_helper,
		(uint32_t) fd,
		str,	
		args);
}

int vprintf(const char* str, va_list args){
	int stdout = 1;
	return __vprintf(
		__fprintf_helper,
		(uint32_t) &stdout,
		str,
		args);
}
int fprintf(FILE *fd,const char* str,...){
	va_list args;
	va_start(args,str);
	int res = vfprintf(fd,str,args);
	va_end(args);
	return res;
}
int printf(const char* str,...){
	va_list args;
	va_start(args,str);
	int res = vprintf(str,args);
	va_end(args);
	return res;
}